/*********************************************************************
 * Módulo 2. Curso de Experto en Desarrollo de Videojuegos
 * Autor: Carlos González Morcillo     Carlos.Gonzalez@uclm.es
 *
 * You can redistribute and/or modify this file under the terms of the
 * GNU General Public License ad published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * and later version. See <http://www.gnu.org/licenses/>.
 *
 * This file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *********************************************************************/
#include "MyFrameListener.h"
#include "ZombieSwarm.h"

MyFrameListener::MyFrameListener
	(Ogre::RenderWindow* win, Ogre::Camera* cam, Ogre::SceneManager* sm) {

	OIS::ParamList param;
	unsigned int windowHandle;
	std::ostringstream wHandleStr;

	_sceneManager = sm;
	_camera = cam;

	win->getCustomAttribute("WINDOW", &windowHandle);
	wHandleStr << windowHandle;
	param.insert(std::make_pair("WINDOW", wHandleStr.str()));

	_inputManager = OIS::InputManager::createInputSystem(param);
	_keyboard = static_cast<OIS::Keyboard*>
		(_inputManager->createInputObject(OIS::OISKeyboard, false));
}

MyFrameListener::~MyFrameListener() {
	_inputManager->destroyInputObject(_keyboard);
	OIS::InputManager::destroyInputSystem(_inputManager);
}

void
MyFrameListener::open() {

	_pd = new OpenSteer::
		BruteForceProximityDatabase<OpenSteer::AbstractVehicle*> ();

	Ogre::Entity* pHumanEnt = _sceneManager->createEntity(HUMANMESH);
	Ogre::SceneNode* pHumanNode = _sceneManager->createSceneNode();
	pHumanNode->attachObject(pHumanEnt);
	_pHuman = new Human(pHumanNode);
	_sceneManager->getRootSceneNode()->addChild(pHumanNode);
	_pZombieSwarm =
		new ZombieSwarm(
			OpenSteer::Vec3(0, 0, 0), NZOMBIES, _pHuman, *_pd, _sceneManager);

	_pHuman->setPosition(
		OpenSteer::randomVectorOnUnitRadiusXZDisk() * MAXDISTANCE);
}

void
MyFrameListener::update(const float currentTime, const float elapsedTime) {

	_pZombieSwarm->update(currentTime, elapsedTime);
	//_pHuman->update(currentTime, elapsedTime);
}

void
MyFrameListener::redraw(const float currentTime, const float elapsedTime) {

	_pZombieSwarm->draw();
	//_pHuman->draw();
}

void
MyFrameListener::close() {

	delete(_pZombieSwarm);
	delete(_pHuman);
}

void
MyFrameListener::reset() {

	_pZombieSwarm->reset();
	_pHuman->reset();
	_pHuman->setPosition(
		OpenSteer::randomVectorOnUnitRadiusXZDisk() * MAXDISTANCE);
}

bool MyFrameListener::frameStarted(const Ogre::FrameEvent& evt) {

	Ogre::Real deltaT = evt.timeSinceLastFrame;

	Ogre::Vector3 vt(0, 0, 0);
	Ogre::Real speed = 10;

	update(0, deltaT);
	redraw(0, deltaT);

	_keyboard->capture();

	// Movimiento humano
	if (_keyboard->isKeyDown(OIS::KC_UP))    vt += Ogre::Vector3(0, 0, -1);
	if (_keyboard->isKeyDown(OIS::KC_DOWN))  vt += Ogre::Vector3(0, 0, 1);
	if (_keyboard->isKeyDown(OIS::KC_LEFT))  vt += Ogre::Vector3(-1, 0, 0);
	if (_keyboard->isKeyDown(OIS::KC_RIGHT)) vt += Ogre::Vector3(1, 0, 0);

	vt.normalise();

	_pHuman->updatePosition(vt * speed * deltaT);

	if (_keyboard->isKeyDown(OIS::KC_R)) reset();

	if (_keyboard->isKeyDown(OIS::KC_ESCAPE)) {
		close();
		return false;
	}

	return true;
}

